/**
 * Translate the abstract tree to some classes and check the syntax
 * @author Baoyouchen
 */
package compiler.absyn;
import java.util.*;

import compiler.errormsg.SyntaxException;
import engine.planner.*;

import storage.record.Schema;
public class Translate {
        java.io.PrintStream out;

        public Translate(java.io.PrintStream o){
                out = o;
        }
        public Object trExp(Exp e){
                if(e instanceof SelectExp) return trExp((SelectExp)e);
                else if(e instanceof UpdateExp) return trExp((UpdateExp)e);
                else if(e instanceof CreateExp) return trExp((CreateExp)e);
                return null;
        }
        public Object trExp(SelectExp e){
                SelectList sl = e.selectlist;
                FromList fl = e.fromlist;
                WhereList p = e.predicate;              
                List<String> slist = new ArrayList<String>();
                List<String> flist = new ArrayList<String>();
                List<QueryData> qlist = new ArrayList<QueryData>();
                List<Term> tlist = new ArrayList<Term>();
                Predicate pre;
                while(sl != null){
                        slist.add(sl.field.idTok);
                        sl = sl.tail;
                }
                while(fl != null){
                		if(fl.name != null)
                			flist.add(fl.name);
                		if(fl.sexp != null)
                			qlist.add((QueryData)trExp(fl.sexp));
                        fl = fl.tail;
                }
                while(p != null){ 
                        tlist.add(p.term);
                        p = p.tail;
                }
                pre = new Predicate(tlist);
                QueryData qd = new QueryData(slist,flist,qlist,pre);
                return qd;
        }
        public Object trExp(UpdateExp e){
                if(e instanceof InsertExp) return trExp((InsertExp) e);
                else if(e instanceof DeleteExp) return trExp((DeleteExp)e);
                else if(e instanceof ModifyExp) return trExp((ModifyExp)e);
                else return 0;
        }
        public Object trExp(CreateExp e){
                if(e instanceof CreateTable) return trExp((CreateTable)e);
                else if(e instanceof CreateView) return trExp((CreateView)e);
                else if(e instanceof CreateIndex) return trExp((CreateIndex)e);
                return null;
        }
        public Object trExp(CreateTable e){
                Schema sc = new Schema();
                String tblname = e.tablename;
                FieldDefs fds = e.fielddefs;
                while(fds != null){
                        FieldDef fd = fds.fielddef;
                        sc.addField(fd.idTok,fd.typedef, fd.key,fd.fk,fd.term);
                        fds = fds.tail;
                }
                return new CreateTableData(tblname,sc);
        }
        public Object trExp(CreateView e){
        		String vewname = e.viewname;
        		QueryData qd = (QueryData)trExp(e.selectexp);
                return new CreateViewData(vewname,qd);
        }
        public Object trExp(CreateIndex e){
        	String fldname = e.fldname;
        	String tblname = e.tblename;
        	return new CreateIndexData(tblname,fldname);
        }
        public Object trExp(InsertExp e){
                String tablename = e.idTok;
                Map<String,Constant> insertInfo = new HashMap<String,Constant>();
                FieldList fldlist = e.fieldlist;
                ConstList vallist = e.constlist;
                while(fldlist != null&&vallist != null){
                        String fldname = fldlist.field.idTok;
                        Constant val = vallist.constant;
                        insertInfo.put(fldname, val);
                        fldlist = fldlist.tail;
                        vallist = vallist.tail;
                }
                InsertData ind = new InsertData(tablename,insertInfo);
                return ind;
        }
        public Object trExp(DeleteExp e){
                String tablename = e.idTok;
                WhereList wl = e.predicate;
                List<Term> tl = new ArrayList<Term>();
                while(wl != null){
                        tl.add(wl.term);
                        wl = wl.tail;
                }
                Predicate pre = new Predicate(tl);
                return new DeleteData(tablename,pre);
        }
        public Object trExp(ModifyExp e){
                String tablename = e.idTok;
                String fldname = e.field.idTok;
                Expression exp = e.expression;
                WhereList wl = e.predicate;
                List<Term> tl = new ArrayList<Term>();
                while(wl != null){
                        tl.add(wl.term);
                        wl = wl.tail;
                }
                Predicate pre = new Predicate(tl);
                return new ModifyData(tablename,fldname,exp,pre);
        }
        
}
